-- «•»«•»«•»«•»«•»«•»«•»«•»«•»«•»«•»«•»«•»«•»«•»«•»«•»«•»«•»«•»«•»«•»«•»«•»

{-
   Contributed by: Daniel Gronau
   last committed by $Author$
   $Revision$
   $Id$
   $Date$
 -}


package test.Test where

import frege.Prelude P ($)

infixl 4 `<$>` `<*>` --`<*` `*>` `<**>` `<$`

main _ = P.println $ (P.`+`) <$> Just 10 <*> Just 4


class Functor this where
    fmap,(<$>) :: (a -> b) -> this a -> this b
    f <$> x = fmap f x

class Apply Functor this => this where
    ap,(<*>) :: this (a -> b) -> this a -> this b
    f <*> x = ap f x

class Applicative Apply this => this where
    return :: a -> this a
    fmap f x = return f <*> x

class Bind Apply this => this where
    (>>=) :: this a -> (a -> this b) -> this b
    (>>)  :: this a -> this b -> this b
    a >> b = a >>= P.const b

-- apx  mf mx = mf >>= (\f -> mx >>= (\x -> return (f x)))

class Monad (Applicative this, Bind this) => this where
    ap mf mx = mf >>= (\f -> mx >>= (\x -> return (f x)))
    fail :: P.String -> this a
    fail s = P.error s

data Maybe a = Nothing | Just a

derive P.Show Maybe a

instance Monad Maybe where
    return a = Just a
    Nothing >>= _ = Nothing
    Just a  >>= k = k a
    fail s = Nothing
